# 文件上传
# 第一种:form 表单上传
<form action='/ajax/upload' enctype="multipart/form-data" type='post' target='uploader'>
<input type='file'>
<input type='hidden' name='userid' value='123'>
<input type='hidden' name='username' value='abc'>
<input type='submit' value='Submit'>
</form>
<iframe id='uploader'></iframe>
小技巧:为 form 设置 target='xxx',xxx 与空 iframe 的id一致,可以避免表单提交后刷新页面。
# 第二种:FormData + ajax 上传
<input type='file' id='file'>
<input type='button' onclick='handleSubmit()'>
function handleSubmit() {
const file = document.getElementById('file').files[0] // blob 数据,即二进制大数据
const formData = new FormData()
formData.append('userid', '123')
formData.append('file', file)
// ajax post 发送
const xhr = new XMLHttpRequest()
xhr.open('POST', '/ajax/upload')
xhr.onload = function () {
if (xhr.status === 200) {
console.log('上传成功');
} else {
console.log('出错了');
}
};
xhr.send(formData)
}
# 第三种:利用 H5 的 FileReader 上传
<div id='preview'></div>
<input type='file' id='file'>
<input type='button' onclick='handleSubmit()'>
function handleSubmit() {
const file = document.getElementById('file').files[0] // blob 数据,即二进制大数据
const reader = new FileReader()
reader.readAsDataURL(file)
reader.onload = function(e) {
const data = e.target.result // base64 数据,假如该文件为图片,此时拿到上传的数据后就可以做预览功能了
// 图片预览
document.getElementById('preview').
// ajax post 发送
const xhr = new XMLHttpRequest()
xhr.open('POST', '/ajax/upload')
xhr.onload = function () {
if (xhr.status === 200) {
console.log('上传成功');
} else {
console.log('出错了');
}
};
xhr.send(data)
}
}
上传图片是可能遇到的问题:
格式转化
图片压缩
// 思路:利用 canvas 实现压缩 file(blob) -> base64 -> image -> canvas压缩 -> base64 /** * fileId - 上传文件的元素id * rate - 压缩率 小于1-压缩 大于1-放大 **/ async function compressPic(fileId, rate) { // 1.获取 blob const file = document.getElementById(fileId).files[0] // blob-二进制大数据 // 2.blob 转 base64 const bs64 = await blob2Base(file).then((e) => { return e.target.result // base64 }) console.log(bs64) // 3.base64 转 image const img = base2Img(bs64) // 4.image 转 canvas const canvas = await img2Canvas(img).then(() => { const canvas = document.createElement('canvas') canvas.width = img.width canvas.height = img.height return canvas }) // 5.压缩并得到压缩后的base64 const newBs64 = doCompress(canvas, img, rate) return newBs64 } function blob2Base(file) { return new Promise((resolve, reject) => { const reader = new FileReader() reader.readAsDataURL(file) reader.onload = (e) => resolve(e) reader.onerror = () => reject('加载失败') }) } function base2Img(bs64) { const img = new Image() img.crossOrigin = '' img.src = bs64 return img } function img2Canvas(img) { return new Promise((resolve, reject) => { img.onload = () => resolve() img.onerror = () => reject('加载失败') }) } function doCompress(canvas, img, rate) { const ctx = canvas.getContext('2d') const canvaswidth = img.width * rate const canvasheight = img.height * rate canvas.width = canvaswidth canvas.height = canvasheight ctx.drawImage(img, 0, 0, img.width, img.height, 0, 0, canvaswidth, canvasheight) const ext = img.src.substring(img.src.lastIndexOf('.') + 1).toLowerCase() const dataURL = canvas.toDataURL('image/' + ext) return dataURL } async function getData() { const data = await compressPic('upload', 0.1) console.log(data) } document.getElementById('upload').addEventListener('change', function() { getData() })